export const metadata = {
  description: "Learn how to set up Jazz in your application."
};

import { Alert, CodeGroup, ContentByFramework, FileName, ReactLogo, SvelteLogo, TabbedCodeGroup, TabbedCodeGroupItem, VanillaLogo } from "@/components/forMdx";
import InstallJazz from '@/components/docs/snippets/InstallJazz.mdx';
import GetAPIKey from '@/components/docs/snippets/GetAPIKey.mdx';

# Installation and Setup

Add Jazz to your application in minutes. This setup covers standard front-end set up, and gives an overview of experimental SSR approaches.

Integrating Jazz with your existing app is straightforward. You'll define data schemas that describe your application's structure, then wrap your app with a provider that handles sync and storage. The whole process takes just three steps:

1. [Install dependencies](#install-dependencies)
2. [Write your schema](#write-your-schema)
3. [Give your app context](#give-your-app-context)

Looking for complete examples? Check out our [example applications](/examples) for chat apps, collaborative editors, and more.

## Install dependencies

First, install the required packages:

<InstallJazz />

## Write your schema

Define your data schema using [CoValues](/docs/core-concepts/covalues/overview) from `jazz-tools`.

<ContentByFramework framework="react">
<FileName>app/schema.ts</FileName>
</ContentByFramework>
<ContentByFramework framework="svelte">
<FileName>src/lib/schema.ts</FileName>
</ContentByFramework>
<CodeGroup>
```ts project-setup/schema.ts
```
</CodeGroup>

See [CoValues](/docs/core-concepts/covalues/overview) for more information on how to define your schema.

## Give your app context
Jazz depends on having context to know who's reading and writing data.

<ContentByFramework framework={['react', 'svelte']}>
You can make sure Jazz always has the right context by wrapping your application with a provider to connect to the Jazz network and define your data schema:
</ContentByFramework>

<ContentByFramework framework="vanilla">
  If you're using vanilla JS, you'll need to manually create a Jazz context and return the API methods necessary for getting the current user, logging the current user out, and accessing the authentication storage.
</ContentByFramework>
<ContentByFramework framework="react">
<FileName>app.tsx</FileName>
</ContentByFramework>
<ContentByFramework framework="svelte">
<FileName>src/routes/+layout.svelte</FileName>
</ContentByFramework>

<TabbedCodeGroup savedPreferenceKey="framework" id="add-provider">
<TabbedCodeGroupItem label="Vanilla JS" value="vanilla" icon={<VanillaLogo />} preferWrap>
```ts jazz.ts
```
</TabbedCodeGroupItem>
<TabbedCodeGroupItem label="React" value="react" icon={<ReactLogo />} preferWrap>
```tsx project-setup/app.tsx
```
</TabbedCodeGroupItem>
<TabbedCodeGroupItem label="Svelte" value="svelte" icon={<SvelteLogo />} preferWrap>
```svelte project-setup/+layout.svelte
```
</TabbedCodeGroupItem>
</TabbedCodeGroup>

<Alert className="mt-4" variant="info" title="Tip">
<GetAPIKey hideCodeGroup={true} hideFileName={true} />
</Alert>

<ContentByFramework framework="vanilla">
## Using your App [!framework=vanilla]
You can start using your app by passing a `sync` parameter and a custom account schema to the `createVanillaJazzApp` factory.
<CodeGroup>
```ts vanilla.ts
```
</CodeGroup>

See [Authentication States](/docs/key-features/authentication/authentication-states#controlling-sync-for-different-authentication-states) for more details on how the `when` property affects synchronisation based on authentication state.

You can find out more about how to [load and subscribe to data here](/docs/vanilla/core-concepts/subscription-and-loading#manual-subscriptions).
</ContentByFramework>

<ContentByFramework framework={['react', 'svelte']}>
This setup handles:
- Connection to the Jazz sync server
- Schema registration for type-safe data handling
- Local storage configuration

With this in place, you're ready to start using Jazz hooks in your components. [Learn how to access and update your data](/docs/core-concepts/subscription-and-loading#subscription-hooks).

## SSR Integration [!framework=react,svelte]

Jazz's default behaviour is to wait until the user's account is loaded before rendering the provider's children. This can be problematic on the server, where no account is available.

We can solve this by asking Jazz to render the children using an a read-only account that can be used without credentials, known as an 'agent'.

Agents can access any data which is available to the public.

### Enabling Provider rendering on the server [!framework=react,svelte]

In order to tell Jazz to allow children to be loaded even in an account-less context, we can set the `enableSSR` setting on the provider.
</ContentByFramework>
<ContentByFramework framework="react">
<FileName>app/components/JazzWrapper.tsx</FileName>
</ContentByFramework>
<ContentByFramework framework="svelte">
<FileName>src/routes/+layout.svelte</FileName>
</ContentByFramework>
<ContentByFramework framework={['react', 'svelte']}>
<TabbedCodeGroup savedPreferenceKey="framework" id="add-ssr">
<TabbedCodeGroupItem label="React" value="react" icon={<ReactLogo />} preferWrap>
```ts project-setup/JazzWrapper.tsx
```
</TabbedCodeGroupItem>
<TabbedCodeGroupItem label="Svelte" value="svelte" icon={<SvelteLogo />} preferWrap>
```svelte project-setup/+layout-with-ssr.svelte
```
</TabbedCodeGroupItem>
</TabbedCodeGroup>
</ContentByFramework>
<ContentByFramework framework="react">
Since the provider is running without an authenticated user, all the `useCoState` and `useAccount` hooks will return null.
</ContentByFramework>
<ContentByFramework framework="svelte">
Since the provider is running without an authenticated user, all the `CoState` and `AccountCoState` instances will return null.
</ContentByFramework>
<ContentByFramework framework={['react', 'svelte']}>
### Load data with an agent [!framework=react,svelte]

In order to actually load and render data, you need to tell Jazz how to do this without an account. We can use the `loadAs` option in our `.load` call, combined with an agent, generated using `createSSRJazzAgent`.

<ContentByFramework framework="react">
<FileName>app/todo/[item]/page.tsx</FileName>
</ContentByFramework>
<ContentByFramework framework="svelte">
<FileName>src/routes/todo/[item]/+page.svelte</FileName>
</ContentByFramework>

<TabbedCodeGroup savedPreferenceKey="framework" id="ssr-page">
<TabbedCodeGroupItem label="React" value="react" icon={<ReactLogo />} preferWrap>
```tsx project-setup/page.tsx
```
</TabbedCodeGroupItem>
<TabbedCodeGroupItem label="Svelte" value="svelte" icon={<SvelteLogo />} preferWrap>
```svelte project-setup/+page.svelte
```
</TabbedCodeGroupItem>
</TabbedCodeGroup>

<Alert variant="info" title="Use .load()" className="mt-4">
  Because subscription hooks can't run on the server, you need to use the `.load()` static method to load data on the server.
</Alert>
</ContentByFramework>
<ContentByFramework framework="react">
Take a look at our [Next.js example](https://github.com/garden-co/jazz/tree/main/examples/jazz-nextjs) to see a complete example of how to use SSR with Jazz.
</ContentByFramework>

<ContentByFramework framework="svelte">
Take a look at our [SvelteKit example](https://github.com/garden-co/jazz/tree/main/examples/jazz-sveltekit) to see a complete example of how to use SSR with Jazz.

For a complete example of Jazz with Svelte, check out our [file sharing example](https://github.com/gardencmp/jazz/tree/main/examples/file-share-svelte) which demonstrates Passkey authentication, file uploads and access control.
</ContentByFramework>

## Further Reading

- [Schemas](/docs/core-concepts/covalues/overview) - Learn about defining your data model
<ContentByFramework framework={['react', 'svelte']}>
- [Provider Configuration](/docs/project-setup/providers) - Learn about other configuration options for Providers
</ContentByFramework>
- [Authentication](/docs/key-features/authentication/overview) - Set up user authentication
- [Sync and Storage](/docs/core-concepts/sync-and-storage) - Learn about data persistence
